#nullable enable
namespace Application.Service.LogCache;

/// <summary>
/// 日志缓存服务
/// <para>功能：全局日志缓存队列对象（单例模式，全局共享）</para>
/// </summary>
public class LogCacheService:ISingleton
{
    /// <summary>
    /// 日志缓存队列（线程安全）
    /// </summary>
    private readonly ConcurrentQueue<LogEntry> _logCache = new ConcurrentQueue<LogEntry>();

    /// <summary>
    /// 最大缓存日志数量
    /// </summary>
    private const int MaxCacheSize = 1000;

    /// <summary>
    /// 日志缓存事件
    /// </summary>
    public event Action<LogEntry>? OnLogAdded;

    /// <summary>
    /// 添加日志到缓存
    /// </summary>
    /// <param name="logEntry">日志条目</param>
    public void AddLog(LogEntry logEntry)
    {
        // 添加到队列
        _logCache.Enqueue(logEntry);

        // 如果超过最大缓存数量，移除最旧的日志
        while (_logCache.Count > MaxCacheSize)
        {
            _logCache.TryDequeue(out _);
        }

        // 触发日志添加事件
        OnLogAdded?.Invoke(logEntry);
    }

    /// <summary>
    /// 获取所有缓存的日志
    /// </summary>
    /// <returns>日志列表</returns>
    public List<LogEntry> GetLogs()
    {
        return _logCache.OrderByDescending(opt=>opt.Timestamp).ToList();
    }

    /// <summary>
    /// 获取最近N条日志
    /// </summary>
    /// <param name="count">数量</param>
    /// <returns>日志列表</returns>
    public List<LogEntry> GetRecentLogs(int count = 100)
    {
        return _logCache.OrderByDescending(opt=>opt.Timestamp).TakeLast(count).ToList();
    }

    /// <summary>
    /// 清空日志缓存
    /// </summary>
    public void Clear()
    {
        _logCache.Clear();
    }

    /// <summary>
    /// 获取缓存中的日志数量
    /// </summary>
    public int Count => _logCache.Count;
}

/// <summary>
/// 日志条目
/// </summary>
public class LogEntry
{
    /// <summary>
    /// 日志时间戳
    /// </summary>
    public DateTime Timestamp { get; set; } = DateTime.Now;

    /// <summary>
    /// 日志级别
    /// </summary>
    public LogLevel Level { get; set; }

    /// <summary>
    /// 日志消息
    /// </summary>
    public string Message { get; set; } = string.Empty;

    /// <summary>
    /// 异常信息
    /// </summary>
    public Exception? Exception { get; set; }

    /// <summary>
    /// 调用者信息
    /// </summary>
    public string? CallerMemberName { get; set; }

    /// <summary>
    /// 调用者文件路径
    /// </summary>
    public string? CallerFilePath { get; set; }

    /// <summary>
    /// 调用者行号
    /// </summary>
    public int CallerLineNumber { get; set; }

    /// <summary>
    /// 格式化日志消息
    /// </summary>
    public override string ToString()
    {
        var logText = $"[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] [{Level}] {Message}";
        
        if (Exception != null)
        {
            logText += $" | 异常: {Exception.Message}";
        }

        if (!string.IsNullOrEmpty(CallerMemberName))
        {
            logText += $" | 调用: {CallerMemberName}";
            if (!string.IsNullOrEmpty(CallerFilePath))
            {
                logText += $" ({CallerFilePath}:{CallerLineNumber})";
            }
        }

        return logText;
    }
}

/// <summary>
/// 日志级别
/// </summary>
public enum LogLevel
{
    Trace,
    Debug,
    Information,
    Warning,
    Error,
    Critical
}
